#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 100005;
struct node{
	int l,r;//起点，终点 
	int add;//标记 
	long long sum;//值 
}tree[maxn<<1+1];
int n,m;
int num[maxn];

inline void read(int &x){
    char c;int f=1;
    while(!isdigit(c=getchar())){
        if(c=='-')f=-1;
    }
    x=c-'0';
    while(isdigit(c=getchar())){
        x=x*10+c-'0';
    }
    x*=f;
}

void build(int fa,int l,int r){//父节点，线段起点，线段终点 
	tree[fa].l=l;
	tree[fa].r=r;
	tree[fa].add=0;
	if(l==r)tree[fa].sum=num[l];
	else{
		int mid=(l+r)>>1;
		build(fa<<1,l,mid);
		build(fa<<1|1,mid+1,r);
		tree[fa].sum=tree[fa<<1].sum+tree[fa<<1|1].sum;
	}
}

inline void pushdown(int fa){//下传标记 
	int len=tree[fa].r-tree[fa].l+1;
	tree[fa<<1].add+=tree[fa].add;
	tree[fa<<1|1].add+=tree[fa].add;
	tree[fa<<1].sum+=(len-(len>>1))*tree[fa].add;
	tree[fa<<1|1].sum+=(len>>1)*tree[fa].add;
	tree[fa].add=0;
}

void update(int fa,int L,int R,int d){//修改（父节点，线段起点，线段终点，修改值） 
	int l=tree[fa].l;
	int r=tree[fa].r;
	if(l==L&&r==R){
		tree[fa].add+=d;
		tree[fa].sum+=(R-L+1)*d;
		return;
	}
	if(tree[fa].add)pushdown(fa);
	int mid=(l+r)>>1;
	if(R<=mid)update(fa<<1,L,R,d);
	else if(L>mid)update(fa<<1|1,L,R,d);
	else{
		update(fa<<1,L,mid,d);
		update(fa<<1|1,mid+1,R,d);
	}
	tree[fa].sum=tree[fa<<1].sum+tree[fa<<1|1].sum;
}

long long find(int fa,int L,int R){//查询（父节点，线段起点，线段终点） 
	int l=tree[fa].l;
	int r=tree[fa].r;
	if(l==L && r==R)return tree[fa].sum;
	if(tree[fa].add)pushdown(fa);
	int mid=(l+r)>>1;
	if(R<=mid)return find(fa<<1,L,R);
	else if(L>mid)return find(fa<<1|1,L,R);
	else return find(fa<<1,L,mid)+find(fa<<1|1,mid+1,R);
}

int main(){
	read(n);read(m);
	for(int i=1;i<=n;i++)read(num[i]);
	build(1,1,n);
	int op,x,y,z;
	for(int i=1;i<=m;i++){
		read(op);read(x);read(y);
		if(op==1){
			read(z);
			update(1,x,y,z);
		}else{
			cout<<find(1,x,y)<<endl;
		}
	} 
	return 0;
}



